<style lang="scss" scoped>
    .ui-select{
        line-height:normal;
        width:175px;
        & /deep/ .el-select__tags-text{
            display:inline-block;
            white-space:nowrap;
        }
    }
    table{
        .ui-select{
            width:100%;
        }
    }
</style>
<template>
    <el-select class="ui-select"
        ref="select"
        v-if="isMounted"
        v-model="model"
        :key="renderKey"
        :multiple="multiple"
        :collapse-tags="collapseTags"
        value-key="id"
        :disabled="disabled"
        :size="size"
        :multiple-limit="multipleLimit"
        :name="name"
        :placeholder="placeholder"
        :clearable="clearable"
        filterable
        :filter-method="onFilter"
        @remove-tag="removeTag"
        @change="onChange"
        @visible-change=" bool => bool && onFilter() "
        @blur="onEnter"
        :default-first-option="defaultFirstOption"
        >
        <el-option v-for="item in currentOption" :key="item.id" :label="item[viewKey]" :value="item" :disabled="item.disabled"></el-option>
    </el-select>
</template>
<script>
    export default {
        name: 'ui-select',
        props: {
            // 新增参数
            'option': null,//不限制类型, 后端给的数据源在一个大obj下面,并没obj.option=[]有初始化过,所以限制类型会报错
            'model-id': String,
            'model-label': String,

            // el-select参数
            'multiple': {
                type: Boolean,
                default: false
            },
            'disabled': {
                default: false
            },
            'size': String,//输入框尺寸
            'multiple-limit': {
                default: 0
            },
            'name': String,
            'placeholder': String,
            'collapse-tags': {
                default: false,
                type: Boolean
            },
            'view-key': {
                type: String,
                default: 'label'
            },
            'clearable': {
                type: Boolean,
                default: false
            },
            'tag-equal': {//标签等宽
                type: Boolean,
                default: false
            },
            'allow-create':{
                type: Boolean,
                default: false
            },
            'default-first-option':{
                type: Boolean,
                default: false
            }
        },
        data() {
            return {
                model: null,
                currentOption: [],   //当前下拉选项
                isMounted: false,
                renderKey: '',
                watchOption:true //监听数据源的开关
            }
        },
        watch: {
            modelId() {
                this.review()
            },
            modelLabel() {
                // 以modelId优先回显
                if (this.modelId === undefined) {
                    this.review()
                }
            },
            option(v) {
                if (this.watchOption) {
                    this.currentOption = Object.assign([], v)
                    this.review()//数据源更新,回显匹配一次
                    this.reRender()
                }
            }
        },
        methods: {
            getItem(key) {// 根据key值从下拉选项中获取指定的一项

                if (this.model == null) {
                    return null //清空时
                }

                let str = ''
                if (this.model.length > 0) {
                    this.model.forEach((item) => {
                        if (item[key]) {
                            str += item[key] + ','
                        }
                    })
                    str = str.replace(/,$/, '')
                }else{
                    str = this.model[key]
                }
                return str
            },
            review() { // 回显匹配
                if (this.option && this.option.length === 0) {
                    return
                }
                let arr = []
                if (this.modelId) {
                    let ids = this.modelId.split(',')
                    ids.forEach((id) => {
                        this.option.forEach((item) => {
                            if (item.id === id) {
                                arr.push(item)
                            }
                        })
                    })
                }else if (this.modelLabel) {
                    let labels = this.modelLabel.split(',')
                    labels.forEach((label) => {
                        this.option.forEach((item) => {
                            if (item[this.viewKey] === label) {
                                arr.push(item)
                            }
                        })
                    })
                }

                if (!this.multiple) {
                    // 单选
                    this.model = arr[0]
                }else{
                    this.model = arr
                }
            },
            onChange(v) {
                // 外传change回调
                this.$emit('change', v)

                // 同步id 和 label
                let id = this.getItem('id')
                let label = this.getItem(this.viewKey)
                this.$emit('update:modelId', id)
                this.$emit('update:modelLabel', label)

                this.setTagWidthEqual();
            },
            removeTag(v) {
                this.$emit('removeTag', v)
            },
            onFilter(v) {
                if (typeof v === 'string' && v !== '') {
                    //匹配 label 和 pinyin_code拼音检索
                    let arr = this.option.filter((item) => {
                        if (item[this.viewKey].indexOf(v) >= 0) {
                            return true
                        }
                        let pinyinCode = item.pinyin_code || item.pinyinCode;
                        if (pinyinCode) {
                            // 忽略拼音检索的大小写
                            let py = pinyinCode.toLowerCase()
                            let val = v.toLowerCase()
                            if (py.indexOf(val) >= 0) {
                                return true
                            }
                        }
                    })
                    this.currentOption = arr
                }else{
                    this.currentOption = this.option
                }

            },
            setTagWidthEqual() {
                if (this.tagEqual && this.multiple) {
                    setTimeout(() => {
                        const tagsText = $(this.$el).find('.el-select__tags-text')
                        tagsText.width('')
                        let w = 0
                        for (let i = 0; i < tagsText.length; i++) {
                            if (tagsText[i].clientWidth > w)
                                w = tagsText[i].clientWidth;
                        }
                        tagsText.width(w)
                    }, 30)
                }
            },
            reRender() {//重新渲染
                this.renderKey = Math.random() + ''
            },
            onEnter(){//回车创建条目
                if (!this.allowCreate || this.multiple) {
                    return
                }

                // 当前输入文本, 创建条目成功后, 以此文本作为 viewKey
                const value = this.$el.querySelector('input').value.trim()
                // 更新当前匹配组 this.currentOption
                if (this.currentOption.find(item => item[this.viewKey] === value)) {
                  return
                }

                // 创建新项
                if (value !== '') {
                    let lastItem = this.option[0]
                    if (lastItem && lastItem._newCreate) {
                        // 修改之前创建的条目
                        lastItem[this.viewKey] = value
                        this.option.shift()
                        this.option.unshift(lastItem)
                    }else{
                        // 创建新条目
                        lastItem = {
                            _newCreate: true
                        }
                        lastItem[this.viewKey] = value

                        // 新项添加到第一条位置, 添加时关闭数据源的监听
                        this.watchOption = false
                        this.option.unshift(lastItem)
                    }
                    this.model = lastItem //保持输入框的值
                    this.onChange(lastItem)
                    this.watchOption = true //开启数据源监听
                }
            }
        },
        created() {
            // 初始化model类型,需要根据 单选/多选 严格区分,避免初始触发不必要的表单校验
            this.model = this.multiple ? [] : ''
        },
        mounted() {

            this.currentOption = Object.assign([], this.option)

            // console.log(this.currentOption)
            if (this.modelId || this.modelLabel) {
                this.review()
            }

            this.isMounted = true //让el-select在ui-select之后执行
        }
    }
</script>
